package Soligee.controller.facade.sessionFacadeImplements;

import Soligee.controller.facade.sessionFacade.SessionFacadeBuscar;
import Soligee.model.vo.cadastros.UsuarioVO;
import java.util.List;
import Soligee.model.persistencia.*;
import Soligee.model.vo.cadastros.FornecedorVO;
import com.icesoft.faces.component.jsfcl.data.DefaultSelectionItems;
import javax.faces.model.SelectItem;
import Soligee.model.vo.cadastros.PessoaFisicaVO;
import Soligee.model.vo.cadastros.PessoaJuridicaVO;
import Soligee.model.vo.cadastros.PessoaVO;
import Soligee.model.vo.cadastros.ProdutoVO;
import Soligee.model.vo.cadastros.RepresentanteVO;
import Soligee.model.vo.cadastros.VendedorVO;
import Soligee.model.vo.lancamentos.NFEntradaVO;
import Soligee.model.vo.lancamentos.OrcamentoVO;
import Soligee.model.vo.lancamentos.PedidoCompraVO;
import java.util.ArrayList;
import java.util.Date;

public class SessionFacadeBuscarImplements implements SessionFacadeBuscar {

   public static final int PESSOA = 0;
   public static final int PESSOAFISICA = 1;
   public static final int PESSOAJURIDICA = 2;
   public static final int PRODUTO = 3;
   public static final int NOTAFISCAL = 4;
   public static final int USUARIO = 5;
   public static final int PEDIDO = 6;
   public static final int VENDEDOR = 7;
   public static final int ORCAMENTO = 8;
   public static final int REPRESENTANTE = 9;
   public static final int FORNECEDOR = 10;
   private CriterioBusca criterioDaBusca;
   private DAO dao;

   /*
   Explicação dos parâmetros para a busca
   -tipo busca: ex. todos,nome, etc
   -classe: classe vo na qual a tabela da busca pertence
   -identificador_tabela: de acordo com as variaveis final no inicio da classe
   -campo desejado: ex. nome, codigo - obs: de acordo com a vo
   -oque busca: oque deseja busca. ex. João;
    */

   //busca pelo login e senha para validar o mesmo
   public boolean buscaLoginSenha(String login, String senha, Class classe) {
      this.setDao(dao = new DAO(classe));
      return this.getDao().buscaPeloLoginSenha(login, senha);
   }

   //retorna o total de registros
   public int totalDeRegistros(Class classe) {
      this.setDao(dao = new DAO(classe));
      return this.getDao().buscaTotalRegistros();
   }//fim totalRegistros

   //busca todos os registros do banco
   public List buscarTodos(String ordenarPor, Class classe) {
      this.setDao(dao = new DAO(classe));
      return (this.getDao().buscarTodos(ordenarPor));
   }//fim buscarTodos

   public List buscarTodosComInativos(String ordenarPor, Class classe) {
      this.setDao(dao = new DAO(classe));
      return (this.getDao().buscarTodosComInativos(ordenarPor));
   }//fim buscarTodos

   public List buscarParcelaPendente(String ordenarPor, Class classe) {
      this.setDao(dao = new DAO(classe));
      return (this.getDao().buscarParcelaPendente(ordenarPor));
   }

   public List buscarPorData(Date data,String ordenarPor, Class classe) {
      this.setDao(dao = new DAO(classe));
      return (this.getDao().buscarPorData(data,ordenarPor));
   }

   public List buscarPorDataGeral(Date data, String colunaDeData, String ordenarPor, Class classe) {
      this.setDao(dao = new DAO(classe));
      return (this.getDao().buscarPorDataGeral(data,colunaDeData,ordenarPor));
   }

   public List buscarParcelaNF(Date data, String colunaDeData, String ordenarPor, Class classe) {
      this.setDao(dao = new DAO(classe));
      return (this.getDao().buscarParcelaNF(data,colunaDeData,ordenarPor));
   }

   public double buscarSoma (Date data, String coluna_a_somar, Class classe){
       this.setDao(dao = new DAO(classe));
       return (this.getDao().buscarSoma(data, coluna_a_somar));
   }

   //busca todos os registros no banco com associacao (join)
   public List buscaTodosComAssociacao(String campo_desejado, Object oque_buscar, String nomeObjetoAsssociado, String ordenarPor, Class classe) {
      this.setDao(dao = new DAO(classe));
      this.setCriterioDaBusca(criterioDaBusca = new CriterioBusca(campo_desejado, oque_buscar));
      return (this.getDao().buscarTodosComAssociacao(nomeObjetoAsssociado, this.getCriterioDaBusca(), ordenarPor));
   }

   //busca no banco por nome, por exemplo "descricao"
   public List buscaPorNome(String campo_desejado, Object oque_buscar, Class classe) {
      this.setDao(dao = new DAO(classe));
      this.setCriterioDaBusca(criterioDaBusca = new CriterioBusca(campo_desejado, oque_buscar));
      return (this.getDao().buscaNome(this.getCriterioDaBusca()));
   }//fim buscaPorNome

   //busca no banco por codigo, ou seja, um numero, por exemplo o rg
   public List buscaPorCodigo(Class classe, String campo_desejado, Object oque_buscar) {
      this.setDao(dao = new DAO(classe));
      this.setCriterioDaBusca(criterioDaBusca = new CriterioBusca(campo_desejado, oque_buscar));
      return (this.getDao().buscarCodigo(this.getCriterioDaBusca()));
   }//fim buscarCodigo

   public List buscarInteiro(Class classe, String coluna, int codigo){
       this.setDao(dao = new DAO(classe));
       return (this.getDao().buscarInteiro(coluna, codigo));
   }

   //o parametro nomeObjetoAssociado é o nome do objeto associado na classe
   public List buscaComAssociacao(String campo_desejado, String oque_buscar, String nomeObjetoAssociado, Class classe) {
      this.setDao(dao = new DAO(classe));
      this.setCriterioDaBusca(criterioDaBusca = new CriterioBusca(campo_desejado, oque_buscar));
      return (this.getDao().buscaComAssociacao(this.getCriterioDaBusca(), nomeObjetoAssociado));
   }

   //o parametro nomeObjetoAssociado é o nome do objeto associado na classe
   public List buscaComAssociacaoSemCriterio(Class classe, String nomeObjetoAssociado) {
      this.setDao(dao = new DAO(classe));
      return (this.getDao().buscaComAssociacaoSemCriterio(nomeObjetoAssociado));
   }

   //busca para realizar a paginacao
   public List buscaComPaginacao(int firstResult, int maxResult, String ordenarPor, Class classe) {
      this.setDao(dao = new DAO(classe));
      return (this.getDao().buscarTodosComPaginacao(firstResult, maxResult, ordenarPor));
   }

   //busca para realizar a paginacao com criterio
   public List buscaComPaginacaoComCriterio(int firstResult, int maxResult, String ordenarPor, String criterioBusca, String oqueBuscar, Class classe) {
      this.setDao(dao = new DAO(classe));
      this.setCriterioDaBusca(criterioDaBusca = new CriterioBusca(criterioBusca, oqueBuscar));
      return (this.getDao().buscarTodosComPaginacaoComCriterio(firstResult, maxResult, ordenarPor, this.getCriterioDaBusca()));
   }

   //busca no banco quando há um item e a necessidade do join
   public List buscaComItem(Class classe, String nomeObjetoAssociado) {
      this.setDao(dao = new DAO(classe));
      return (this.getDao().buscaComItem(nomeObjetoAssociado));
   }

   //busca no banco quando há um item e a necessidade do join com algum criterio, ou seja, clausula where
   public List buscaComItemCriteriosa(String campo_desejado, Object oque_buscar, String nomeObjetoAssociado, Class classe) {
      this.setDao(dao = new DAO(classe));
      this.setCriterioDaBusca(criterioDaBusca = new CriterioBusca(campo_desejado, oque_buscar));
      return (this.getDao().buscaComItemCriteriosa(this.getCriterioDaBusca(), nomeObjetoAssociado));
   }


   //busca para realizar o autocomplete das interfaces
   public DefaultSelectionItems consultaSelectInputText(int identificador_tabela, String campoConsultar, String valorConsultar, Class classe) {
      DefaultSelectionItems itens = new DefaultSelectionItems();
      itens.clear();
      int i = 0;
      switch (identificador_tabela) {
         case PESSOA: //PESSOA VO
            List<PessoaVO> listaPessoa = this.buscaPorNome(campoConsultar, valorConsultar + "%", classe);
            while (i < listaPessoa.size()) {
               itens.add(new SelectItem(listaPessoa.get(i).getCodPessoa(), listaPessoa.get(i).getNome()));
               i++;
            }//fim while
            break;
         case PESSOAFISICA: //PESSOAFISICA

            List<PessoaFisicaVO> lista_pessoa = this.buscaPorNome(campoConsultar, valorConsultar + "%", classe);
            while (i < lista_pessoa.size()) {
               itens.add(new SelectItem(lista_pessoa.get(i).getCodPessoa(), lista_pessoa.get(i).getNome()));
               i++;
            }//fim while

            break;
         case PESSOAJURIDICA: //PESSOAJURIDICA
            List<PessoaJuridicaVO> listaPessoaJuridica = this.buscaPorNome(campoConsultar, valorConsultar + "%", classe);
            if (campoConsultar.equals("cnpj")) {//se for para montar por cnpj
               while (listaPessoaJuridica.iterator().hasNext()) {
                  System.out.println(listaPessoaJuridica.iterator().next().getCnpj());
                  itens.add(new SelectItem(listaPessoaJuridica.iterator().next(), listaPessoaJuridica.iterator().next().getCnpj()));
                  listaPessoaJuridica.remove(listaPessoaJuridica.iterator().next());
               }//fim while
            } else {
               while (i < listaPessoaJuridica.size()) {
                  itens.add(new SelectItem(listaPessoaJuridica.get(i).getCodPessoa(), listaPessoaJuridica.get(i).getNome()));
                  i++;
               }//fim while
            }//fim do else
            break;
         case PRODUTO: //Produto
            List<ProdutoVO> lista_produtos = this.buscaPorNome(campoConsultar, valorConsultar + "%", classe);
            while (i < lista_produtos.size()) {
               itens.add(new SelectItem(lista_produtos.get(i).getCodProduto(), lista_produtos.get(i).getDescricao()));
               i++;
            }//fim while
            break;
         case NOTAFISCAL://nota fiscal
            List<NFEntradaVO> listaNotaFiscal = this.buscaPorCodigo(classe, campoConsultar, valorConsultar);
            while (i < listaNotaFiscal.size()) {
               itens.add(new SelectItem(listaNotaFiscal.get(i).getCodNFEntrada(), String.valueOf(listaNotaFiscal.get(i).getNumeroNFEntrada())));
               i++;
            }//fim while
            break;
         case USUARIO://usuario
            List<UsuarioVO> lista = this.buscaPorNome(campoConsultar, valorConsultar + "%", classe);
            System.out.println(campoConsultar);
            if (campoConsultar.equals("login")) {
               while (i < lista.size()) {
                  itens.add(new SelectItem(lista.get(i).getCodUsuario(), lista.get(i).getLogin()));
                  i++;
               }//fim while}
            } else {
               while (i < lista.size()) {
                  itens.add(new SelectItem(lista.get(i).getCodUsuario(), lista.get(i).getNome()));
                  i++;
               }//fim while}
            }
            break;
         case VENDEDOR://vendedor
            List<VendedorVO> lista_vendedor = this.buscaPorNome(campoConsultar, valorConsultar + "%", classe);
            while (i < lista_vendedor.size()) {
               itens.add(new SelectItem(lista_vendedor.get(i).getCodVendedor(), lista_vendedor.get(i).getNome()));
               i++;
            }//fim while
            break;
         case ORCAMENTO://orcamento
            //se autocompletar com nome do cliente
            if (campoConsultar.equals("pessoa")) {
               List<OrcamentoVO> lista_orcamentoCliente = this.buscaComAssociacao("nome", valorConsultar+"%", campoConsultar,classe);
               while (i < lista_orcamentoCliente.size()) {
                  itens.add(new SelectItem(lista_orcamentoCliente.get(i).getCodOrcamento(), lista_orcamentoCliente.get(i).getPessoa().getNome()));
                  i++;
               }//fim while
            }//fim if
            //se autocompletar com nome do vendedor
            if (campoConsultar.equals("vendedor")) {
               List<OrcamentoVO> lista_orcementoVendedor = this.buscaComAssociacao(campoConsultar, valorConsultar + "%", "vendedor", classe);
               while (i < lista_orcementoVendedor.size()) {
                  itens.add(new SelectItem(lista_orcementoVendedor.get(i).getCodOrcamento(), lista_orcementoVendedor.get(i).getVendedor().getNome()));
                  i++;
               }//fim while
            }//fim if
            break;
         case REPRESENTANTE: //representante
            List<RepresentanteVO> listaRepresentantes = this.buscaPorNome(campoConsultar, valorConsultar + "%", classe);
            while (i < listaRepresentantes.size()) {
               itens.add(new SelectItem(listaRepresentantes.get(i).getCodPessoa(), listaRepresentantes.get(i).getNome()));
               i++;
            }//fim while
            break;
         case FORNECEDOR://fornecedor
            //se autocompletar com nome do fornecedor
            List<FornecedorVO> listaFornecedores = this.buscaPorNome(campoConsultar, valorConsultar + "%", classe);
            if (campoConsultar.equals("razaoSocial")) {
               while (i < listaFornecedores.size()) {
                  if (!listaFornecedores.get(i).getPedidosdecompras().isEmpty()) {
                     itens.add(new SelectItem(listaFornecedores.get(i).getCodPessoa(), listaFornecedores.get(i).getRazaoSocial()));
                  }
                  i++;
               }//fim while
            } else {
               while (i < listaFornecedores.size()) {
                  if (!listaFornecedores.get(i).getPedidosdecompras().isEmpty()) {

                     itens.add(new SelectItem(listaFornecedores.get(i).getCodPessoa(), listaFornecedores.get(i).getNome()));
                  }
                  i++;
               }//fim while
            }
            break;

         case PEDIDO://pedido
            //se autocompletar com nome do fornecedor do pedido
            List<PedidoCompraVO> listaPedido = new ArrayList<PedidoCompraVO>();
            //neste caso o campo a consulta é o objeto associado ao pedido de compra
            if (campoConsultar.equals("representante")) {
               listaPedido = this.buscaComAssociacao("nome", valorConsultar + "%", campoConsultar, PedidoCompraVO.class);
               while (i < listaPedido.size()) {
                  itens.add(new SelectItem(listaPedido.get(i).getCodPedido(), listaPedido.get(i).getRepresentante().getNome()));

                  i++;
               }//fim while
            } else if (campoConsultar.equals("fornecedor")) {
               listaPedido = this.buscaComAssociacao("nome", valorConsultar + "%", campoConsultar, PedidoCompraVO.class);
               while (i < listaPedido.size()) {
                  itens.add(new SelectItem(listaPedido.get(i).getCodPedido(), listaPedido.get(i).getFornecedor().getNome()));
                  i++;
               }//fim while
            } else if (campoConsultar.equals("dataEmissao")) {
               listaPedido = this.buscaComAssociacao("data", valorConsultar + "%", campoConsultar, PedidoCompraVO.class);
               while (i < listaPedido.size()) {
                  itens.add(new SelectItem(listaPedido.get(i).getCodPedido(), listaPedido.get(i).getDataEmissao().toString()));
                  i++;
               }//fim while
            }
            break;

         default:
            System.out.println("Erro: Opção Inválida no ajax");
            break;
      }
      return itens;
   }//fim consulta selectInputText

   //métodos gets e sets
   private CriterioBusca getCriterioDaBusca() {
      return criterioDaBusca;
   }

   private void setCriterioDaBusca(CriterioBusca criterioDaBusca) {
      this.criterioDaBusca = criterioDaBusca;
   }

   private DAO getDao() {
      return dao;
   }

   private void setDao(DAO dao) {
      this.dao = dao;
   }
}//fim classe
